/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package net.learntechnology.ajax;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.text.DecimalFormat;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.sql.*;

import java.io.*;
import org.w3c.dom.Document;
import org.w3c.dom.*;
import org.apache.xpath.XPathAPI;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.InputSource;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.learntechnology.ajax.FileUploadListener;

import net.learntechnology.ajax.FileUploadListener.FileUploadStats;
import net.learntechnology.ajax.FileUploadListener.FileUploadStatus;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import com.missiondata.fileupload.MonitoredDiskFileItemFactory;

import properties.LoadProperties;
import java.net.*;
import javax.servlet.RequestDispatcher;
import javax.servlet.http.HttpSession;
import openaccessagrovoctagger.OpenAccessAgrovocTagger;
import openaccessagrotagtagger.OpenAccessAgrotagTagger;

import javax.ws.rs.core.Context;
import javax.ws.rs.core.UriInfo;
import javax.ws.rs.PathParam;
import javax.ws.rs.Consumes;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Produces;
import javax.ws.rs.FormParam;

import java.util.HashMap;
/**
 * REST Web Service
 *
 * @author dspace
 */

@Path("agrotags")
public class AgrotagsResource {

    private HashMap parameters = new HashMap();

       public int num=0;

    public static LoadProperties lp = new LoadProperties();
    private static String rootPath =  lp.getRootPath();
    public static String dbName = lp.getDatabaseName();
    public static String dbNameAgrovoc = lp.getDatabaseAgrovocName();
    public static String dbConnIP = lp.getDatabaseConnectionIP();
    public static String dbConnPort = lp.getDatabaseConnectionPort();
    public static String dbUser = lp.getDatabaseUser();
    public static String dbPwd = lp.getDatabasePwd();

     public static String dbPath = "jdbc:mysql://" + dbConnIP + ":" + dbConnPort + "/" + dbName + "?" +
                            "user=" + dbUser +"&password=" + dbPwd;
    public static String dbPathAgrovoc = "jdbc:mysql://" + dbConnIP + ":" + dbConnPort + "/" + dbNameAgrovoc + "?" +
                            "user=" + dbUser +"&password=" + dbPwd;
     
    @Context
    private UriInfo context;

    /** Creates a new instance of AgrotagsResource */
    public AgrotagsResource() {
    }

    /**
     * Retrieves representation of an instance of net.learntechnology.ajax.AgrotagsResource
     * @return an instance of java.lang.String
     */

    
    @POST
    public void getAgrotags(@Context HttpServletRequest request, @Context HttpServletResponse response) throws ServletException, IOException {


           String rootPath =  lp.getRootPath();

            System.out.println("What is the root path" + rootPath);
            String saveFilePath = rootPath + "Agrotagger/uploaded_files/";


            String FILENAME = null;
            String paramsXML = "TEST";
            String tagSet = null;
            
            String fileXML = null;

            String Output = null;
        	int flag=0;

        try {

            FileUploadListener listener = new FileUploadListener(request.getContentLength());
            request.getSession().setAttribute("FILE_UPLOAD_STATS", listener.getFileUploadStats());
            DiskFileItemFactory factory = new MonitoredDiskFileItemFactory(listener);
            factory.setRepository(new File(saveFilePath));
            ServletFileUpload upload = new ServletFileUpload(factory);
            List items = upload.parseRequest(request);
            int mnid=0;
            String tags=null;

            for (Iterator i = items.iterator(); i.hasNext();) {
                FileItem fileItem = (FileItem) i.next();
                if (!fileItem.isFormField()) {
                    String filename=fileItem.getName();
                    String[] file_ext=filename.split("\\.");
                    String[] exten={"doc","ppt","pdf","docx","pptx","odt","odp"};
                    
                    for(int in=0;in<exten.length;in++)
                        {
                            if(exten[in]==file_ext[1])
                            {
                                break;
                            }
                            else
                            {
                                System.out.println("<b>"+fileItem.getName()+"is an invalid file type!</b>");
                                request.getSession().setAttribute("file_name", fileItem.getName());
                                flag=1;
                                break;

                             }
                     }

                    if(flag==1)
                    {
                       System.out.println("<b>"+fileItem.getName()+"is an invalid file type!</b>");
                    }

                      //connection with mysql db

                    try {
                            Connection con = null;
                            Statement stmt=null;
                            ResultSet rst=null;
                            ResultSet rst1=null;
                            Class.forName("com.mysql.jdbc.Driver").newInstance();

                           /* Create a connection by using getConnection() method that takes parameters of
                           string type connection url, user name and password to connect to database. */
                           con = DriverManager.getConnection(dbPath);//connectionURL, "root", "gaurav");

                          // check weather connection is established or not by isClosed() method
                           if(!con.isClosed())
                               System.out.println("Successfully connected to " + "MySQL server using TCP/IP...");
                               // out.println("Successfully connected to " + "MySQL server using TCP/IP...");
                               stmt=con.createStatement();
                               rst=stmt.executeQuery("SELECT max(vid) as vid FROM node");
                               while(rst.next())
                               {
                                   num=rst.getInt("vid");
                                   //out.println("vid "+num);
                                }
                                num++;
                                mnid = num;
                                String node_file_entry="tagger_file"+num;
                                fileXML = "tagger_file"+num+".xml";
                                String file_name="tagger_file"+num+"."+file_ext[1];
                                FILENAME = file_name;
                                System.out.println("file name ----------------  "+file_name);
                                fileItem.write(new File(saveFilePath + file_name));


                                String node="INSERT INTO node (nid, vid, type, language, title, uid, status, created, changed, comment, promote, moderate, sticky, tnid, translate) VALUES("+num+","+num+",'tagger','en','"+node_file_entry+"',24,1,1266580154,1266580154,0,0,0,0,0,0)";
                                int n=stmt.executeUpdate(node);
                                System.out.println("node entry "+n);

                                String upload_tb="INSERT INTO upload VALUES("+num+","+num+","+num+",'"+file_name+"',1,0)";
                                int u= stmt.executeUpdate(upload_tb);
                                System.out.println("upload entry "+u);


                                String file="INSERT INTO files VALUES("+num+",1,'"+file_name+"','"+"root/Agrotagger/uploaded_files/"+file_name+"','application/pdf',27898,1,1266580154)";
                                int f= stmt.executeUpdate(file);
                                System.out.println("file entry "+f);


                                con.close();
                                        }
                    catch(Exception ex)
                    {
                        System.out.println("exception in connection "+ex.getMessage());
                     }
               } else {
                    parameters
                            .put(fileItem.getFieldName(), fileItem.getString("UTF-8"));
               }
            }

        paramsXML = (String) parameters.get("paramsXML");

        String[] params = getParameters(paramsXML);

        if(params[2].equals("agrovoc"))
        {
            OpenAccessAgrovocTagger voc = new OpenAccessAgrovocTagger();
            tagSet = voc.tag_generation(mnid, Integer.parseInt(params[1]));
        }
        else
           if(params[2].equals("agrotag"))
        {
           OpenAccessAgrotagTagger oa= new OpenAccessAgrotagTagger();
           tagSet = oa.tag_generation(mnid, Integer.parseInt(params[1]));
        }


                if (params[0].equals("xml/rdf")) {
                    Output = getRDFOutput(tagSet, params[2], FILENAME);
                    File file = null;
                    try {
                        Writer output = null;
                         file = new File(rootPath + "Agrotagger/xml_files/" + fileXML);
                         output = new BufferedWriter(new FileWriter(file));
                         output.write(Output);
                         output.close();
                    } catch(IOException ioe){
                        
                    }
                    response.setContentType("xml/rdf;charset=UTF-8");
                    response.setHeader("Content-Disposition", "attachment;filename=" + fileXML);

                    InputStream is = new FileInputStream(file);
                    BufferedInputStream input = new BufferedInputStream(is);
                    BufferedOutputStream output = new BufferedOutputStream(response.getOutputStream());
                    copy(input, output);
                    is.close();
                    response.getOutputStream().flush();
                    output.flush();
                } else 
                if (params[0].equals("application/json")) {
                    Output = getJSONOutput(tagSet);
                    response.setContentType("application/json;charset=UTF-8");
                }else
                if (params[0].equals("text/plain")) {
                    Output = getTEXTOutput(tagSet);
                    response.setContentType("text/plain;charset=UTF-8");
                }
            System.out.println("Files finished being written to file system at "+saveFilePath );
          //  request.getSession().invalidate();
        } catch (Exception e) {
            //to be safe put error in stats so that our ajax progress can pick this up
            FileUploadStats stats = new FileUploadListener.FileUploadStats();
            stats.setCurrentStatus(FileUploadStatus.ERROR);
            request.getSession().setAttribute("FILE_UPLOAD_STATS", stats);
            e.printStackTrace();
            System.out.println("exception in fileuploadservlet "+e.getMessage());
        }



    PrintWriter out = response.getWriter();
    out.write(Output);

    System.out.println("leaving doPost");
    out.close();
    //    return Output;
    }

    public String[] getParameters(String paramsXML){
        String[] params = {"xml/rdf", "10", "agrotag"};
        try{
            DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();

            InputSource is = new InputSource();
            is.setCharacterStream(new StringReader(paramsXML));

            Document doc = docBuilder.parse (is);

            NodeList listOfBooks = XPathAPI.selectNodeList(doc, "params");

        //System.out.println("No. of Books : " + listOfBooks.getLength());

            for(int s=0; s<listOfBooks.getLength() ; s++){
                       Node bookNode = listOfBooks.item(s);


                    Element bookElement = (Element)bookNode;

                    //-------
                    NodeList dcNodes = bookElement.getElementsByTagName("processingDirectives");
       //                NodeList dcNodes = bookNode.getChildNodes();

                for (int k = 0; k < dcNodes.getLength(); k++)
                {
                    Node n = dcNodes.item(k);
                    NamedNodeMap nm = n.getAttributes();

                    for (int i = 0; i < nm.getLength(); i++)
                    {
                        Node node = nm.item(i);

                        if (("outputType").equals(node.getNodeName()))
                        {
                                params[0]= node.getNodeValue();
                        }
                        if (("noOfTags").equals(node.getNodeName()))
                        {
                                params[1]= node.getNodeValue();
                        }
                        if (("vocabularyType").equals(node.getNodeName()))
                        {
                                params[2]= node.getNodeValue();
                        }
                    }

                }
         }

        }catch (SAXParseException err) {
        System.out.println ("** Parsing error" + ", line "
             + err.getLineNumber () + ", uri " + err.getSystemId ());
        System.out.println(" " + err.getMessage ());

        }catch(IOException ioe) {
        }catch (SAXException e) {
                Exception x = e.getException ();
                        ((x == null) ? e : x).printStackTrace ();
        }catch (Throwable t) {
                t.printStackTrace ();
        }
        return params;
    }

    public String getRDFOutput(String tagSet, String vocabulary, String fileName) {
        String[] temp_tags = tagSet.split("\\|");
        String[] termCodes = getTermCodes(temp_tags);

        String RDF = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
                     "<rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n" +
                     "xmlns:Tagger=\"http://agropedialabs.iitk.ac.in/Tagger#\">\n";


        RDF =  RDF + "<rdf:Description rdf:about=\"" + fileName + "\">\n" ;

        for ( int i=0 ; i < temp_tags.length; i++) {
            if (vocabulary.equals("agrotag")) {
                RDF = RDF + "<Tagger:agrotags_" + (i+1) + ">" + temp_tags[i].trim() + "</Tagger:agrotags_" + (i+1) + ">\n";
                RDF = RDF + "<Tagger:autoTaggeruri" + (i+1) + ">http://aims.fao.org/aos/agrovoc/c_" + termCodes[i] + "</Tagger:autoTaggeruri" + (i+1) + ">\n";
            }
            if (vocabulary.equals("agrovoc")) {
                RDF = RDF + "<Tagger:agrovoc_" + (i+1) + ">" + temp_tags[i].trim() + "</Tagger:agrovoc_" + (i+1) + ">\n";
                RDF = RDF + "<Tagger:autoTaggeruri" + (i+1) + ">http://aims.fao.org/aos/agrovoc/c_" + termCodes[i] + "</Tagger:autoTaggeruri" + (i+1) + ">\n";
            }

        }

        RDF = RDF + "</rdf:Description>\n";
        RDF = RDF + "</rdf:RDF>\n";

        return RDF;
    }

    public String getJSONOutput(String tagSet) {
        String[] temp_tags = tagSet.split("\\|");
        String JSON = null;

        JSON = "{";

        for ( int i=0 ; i < temp_tags.length; i++) {
            JSON = JSON + "\"" + temp_tags[i].trim() + "\"";
            if(!(i == temp_tags.length-1)) JSON = JSON + ", ";
        }
        JSON = JSON + "}";

        return JSON;
    }

    public String getTEXTOutput(String tagSet) {
        String[] temp_tags = tagSet.split("\\|");
        String TEXT = "";

        for ( int i=0 ; i < temp_tags.length; i++) {
            TEXT = TEXT + temp_tags[i].trim();
            if(!(i == temp_tags.length-1)) TEXT = TEXT + ", ";
        }

        return TEXT;
    }

    public String[] getTermCodes(String[] tags) {

        String[] termCodes = new String[tags.length];

        for(int i=0; i< tags.length; i++) {
            termCodes[i] = "NOT-AVAILABLE";
        }


        try {
                            Connection con = null;
                            Statement stmt=null;
                            ResultSet rst=null;
                            Class.forName("com.mysql.jdbc.Driver").newInstance();

                           /* Create a connection by using getConnection() method that takes parameters of
                           string type connection url, user name and password to connect to database. */
                           con = DriverManager.getConnection(dbPathAgrovoc);//connectionURL, "root", "gaurav");

                          // check weather connection is established or not by isClosed() method
                           if(!con.isClosed()){
                               System.out.println("Successfully connected to " + "MySQL AGROVOCNEW server using TCP/IP...");
                               stmt=con.createStatement();
                               for (int i=0; i < tags.length; i++) {
                                    String sqlQuery = "SELECT termcode FROM agrovocterm where termspell='" + tags[i].trim() + "' and languagecode='en'";
                                    System.out.println("AGROVOC NEW QUERY ==> " + sqlQuery);
                                    rst=stmt.executeQuery(sqlQuery);
                                    while(rst.next())
                                    {
                                        termCodes[i] = Integer.toString(rst.getInt("termcode"));
                                    }
                                }
                          }
                           con.close();
        } catch (Exception e) {

        }

        return termCodes;
    }
        public static void copy(InputStream input, OutputStream output)
            throws IOException
    {
        final int BUFFER_SIZE = 1024 * 4;
        final byte[] buffer = new byte[BUFFER_SIZE];

        while (true)
        {
            final int count = input.read(buffer, 0, BUFFER_SIZE);

            if (-1 == count)
            {
                break;
            }

            // write out those same bytes
            output.write(buffer, 0, count);
        }

        // needed to flush cache
        // output.flush();
    }

 }
